﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Data.SQLite;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using UCLibrary;
using static System.Net.Mime.MediaTypeNames;

namespace 项目框架
{
    public partial class FrmAlarm : Form
    {
        bool simAlarm = false;
        System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
        Data1[] data;
        DataTable dataTable = new DataTable();
        DataTable actualAlarmDataTable = new DataTable();
        SQLiteConnection upsqlCnt = new SQLiteConnection();
        SQLiteCommand upcommand = new SQLiteCommand();
        SQLiteTransaction upTransaction;
        Stopwatch stopwatch = new Stopwatch();
        int page;

        public FrmAlarm()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer //双缓冲
                | ControlStyles.ResizeRedraw
               | ControlStyles.AllPaintingInWmPaint, //不擦除背景，减少闪烁
                true);
            this.UpdateStyles();

            //利用反射设置DataGridView的双缓冲
            Type dgvType = this. dataGridView2.GetType();
            PropertyInfo pi = dgvType.GetProperty("DoubleBuffered",
               BindingFlags.Instance | BindingFlags.NonPublic);
            pi.SetValue(this.dataGridView2, true, null);

            #region 测试报警

            //给data赋值
            data = new Data1[]
            {
                new Data1()
               {
                    SN = "0"
                    ,Status = false
                    ,StartTime = "0"
                    ,EndTime="0"
                    ,AlarmText="这是第0号报警"
               },
                new Data1()
               {
                    SN = "1"
                    ,Status = false
                    ,StartTime = "0"
                    ,EndTime="0"
                    ,AlarmText="这是第1号报警"
               },
                new Data1()
               {
                    SN = "0"
                    ,Status = false
                    ,StartTime = "0"
                    ,EndTime="0"
                    ,AlarmText="这是第2号报警"
               },
                new Data1()
               {
                    SN = "0"
                    ,Status = false
                    ,StartTime = "0"
                    ,EndTime="0"
                    ,AlarmText="这是第3号报警"
               },
                new Data1()
               {
                    SN = "0"
                    ,Status = false
                    ,StartTime = "0"
                    ,EndTime="0"
                    ,AlarmText="这是第4号报警"
               },
                new Data1()
               {
                    SN = "0"
                    ,Status = false
                    ,StartTime = "0"
                    ,EndTime="0"
                    ,AlarmText="这是第5号报警"
               },
                new Data1()
               {
                    SN = "0"
                    ,Status = false
                    ,StartTime = "0"
                    ,EndTime="0"
                    ,AlarmText="这是第6号报警"
               },
                new Data1()
               {
                    SN = "0"
                    ,Status = false
                    ,StartTime = "0"
                    ,EndTime="0"
                    ,AlarmText="这是第7号报警"
               },
            };
            //将每个事件都添加
            for (int i = 0; i < data.Length; i++)
            {
                data[i].Aevent += UpdateAlarm;
            }
            #endregion 测试报警

            #region 数据表初始化
            actualAlarmDataTable.Clear();
            actualAlarmDataTable.Columns.Add("报警代码", typeof(int));
            actualAlarmDataTable.Columns.Add("开始时间", typeof(string));
            actualAlarmDataTable.Columns.Add("报警文本", typeof(string));

            dataTable.Clear();
            dataTable.Columns.Add("报警代码", typeof(int));
            dataTable.Columns.Add("开始时间", typeof(string));
            dataTable.Columns.Add("结束时间", typeof(string));
            dataTable.Columns.Add("报警文本", typeof(string));
            #endregion 数据表初始化

            #region 定时器初始化
            timer.Tick += timerTick;
            timer.Interval = 100;
            timer.Start();
            #endregion 定时器初始化

            #region 数据库初始化
            upsqlCnt = new SQLiteConnection("Data Source=历史报警.db;Version=3;");//新建库对象
            upsqlCnt.Open();
            upcommand = new SQLiteCommand();//新建命令对象
            upcommand.Connection = upsqlCnt;//和数据库连接
            upcommand.Connection = upsqlCnt;
            upcommand.CommandText = @"CREATE TABLE IF NOT EXISTS '历史报警' (报警代码 INTEGER, 开始时间 TEXT,结束时间 TEXT,报警文本 TEXT)";
            upcommand.ExecuteNonQuery();
            upTransaction = upsqlCnt.BeginTransaction();
            #endregion
            stopwatch.Restart();
        }
        /// <summary>
        /// 更新报警数据
        /// </summary>
        /// <param name="b1">信号状态</param>
        /// <param name="s1">报警代码</param>
        /// <param name="s2">开始时间</param>
        /// <param name="s3">结束时间</param>
        /// <param name="s4">报警文本</param>
        private void UpdateAlarm(bool b1, string s1,string s2,string s3,string s4)
        {
            if(b1)//为真需要显示在实时报警中
            {
                actualAlarmDataTable.Rows.Add(s1,s2,s4);
            }
            else//为假需要写入数据库中,并且从当前报警中移除
            {
                for (int i = 0;i < actualAlarmDataTable.Rows.Count; i++)
                {
                    var x = actualAlarmDataTable.Rows[i].ItemArray;
                    //for (int j = 0; j < x.Length; j++)
                    {
                        if (x[2].ToString()==s4)
                        {
                            DataRow datarow = actualAlarmDataTable.Rows[i];
                            actualAlarmDataTable.Rows.Remove(datarow);
                        }
                    }
                }
                upcommand.CommandText = "INSERT INTO 历史报警 (报警代码,开始时间,结束时间,报警文本) VALUES ($a,$b,$c,$d);";
                upcommand.Parameters.AddWithValue("$a",s1);
                upcommand.Parameters.AddWithValue("$b", s2);
                upcommand.Parameters.AddWithValue("$c", s3);
                upcommand.Parameters.AddWithValue("$d", s4);
                upcommand.ExecuteNonQuery();
            }
        }
        private void timerTick(object sender, EventArgs e)
        {
            if (stopwatch.ElapsedMilliseconds >=1000)
            {
                stopwatch.Restart();
                upTransaction.Commit();
                upTransaction = upsqlCnt.BeginTransaction();
            }
            //模拟闪烁的报警
            if (simAlarm)
                for (int i = 0; i < data.Length; i++)
                {
                    data[i].Status = !data[i].Status;
                }
        }
        private void FrmAlarm_Load(object sender, EventArgs e)
        {
            dateTimePicker1.CustomFormat = "yyyy/MM/dd HH:mm:ss";
            dateTimePicker1.Format = System.Windows.Forms.DateTimePickerFormat.Custom;
            dateTimePicker2.CustomFormat = "yyyy/MM/dd HH:mm:ss";
            dateTimePicker2.Format = System.Windows.Forms.DateTimePickerFormat.Custom;
            dataGridView1.DataSource = actualAlarmDataTable;
            dataGridView1.Columns["报警代码"].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
            dataGridView1.Columns["开始时间"].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
            dataGridView1.Columns["报警文本"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            dataGridView1.Sort(dataGridView1.Columns["开始时间"], ListSortDirection.Descending);
            dataGridView1.AllowUserToResizeColumns = false; // 禁止用户改变DataGridView的所有列的列宽
            dataGridView1.AllowUserToResizeRows = false;//禁止用户改变DataGridView所有行的行高
            dataGridView1.ReadOnly = true;//禁止用户修改值
            dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;//设定选择模式为选择整行
            dataGridView1.MultiSelect = false;//是否可以多选
        }
        private void FrmAlarm_FormClosed(object sender, FormClosedEventArgs e)
        {
            upTransaction.Commit();
            upTransaction.Dispose();
            upcommand.Dispose();
            upsqlCnt.Dispose();
            timer.Stop();
            for (int i = 0;i<input.boolsOld.Length;i++)
            {
                input.boolsOld[i] = false;
            }
        }

        private void ucBtn2_Click(object sender, EventArgs e)
        {
            data[1].Status = !data[1].Status;
        }
        private void UpdataHistory()
        {
            SQLiteConnection sqlCnt = new SQLiteConnection("Data Source=历史报警.db;Version=3;");//新建库对象
            sqlCnt.Open();
            SQLiteCommand command = new SQLiteCommand();//新建命令对象
            command.Connection = sqlCnt;//和数据库连接
            command.Connection = sqlCnt;
            command.CommandText = @"CREATE TABLE IF NOT EXISTS '历史报警' (报警代码 INTEGER, 开始时间 TEXT,结束时间 TEXT,报警文本 TEXT)";
            command.ExecuteNonQuery();
            //command.CommandText = "SELECT * FROM 历史报警 WHERE 开始时间>= $BB AND 开始时间<= $AA ORDER BY 开始时间 DESC";
            //command.Parameters.AddWithValue("$AA", dateTimePicker2.Value.ToString("s"));
            //command.Parameters.AddWithValue("$BB", dateTimePicker1.Value.ToString("s"));
            command.CommandText = string.Format("SELECT * FROM 历史报警 WHERE 开始时间>= '{0}' AND 开始时间<= '{1}' ORDER BY 开始时间 DESC;", dateTimePicker1.Value.ToString("s"), dateTimePicker2.Value.ToString("s"));
            DataSet ds = new DataSet();
            SQLiteDataAdapter sQLiteDataAdapter = new SQLiteDataAdapter(command);
            sQLiteDataAdapter.Fill(ds, "历史报警"); //填充数据集
            dataTable = ds.Tables["历史报警"]; //创建表
            command.Dispose();
            sqlCnt.Dispose();
            Invoke(new Action(() =>
            {
                label2.Text = dataTable.Rows.Count.ToString();
                dataGridView2.DataSource = dataTable;
                //使用AllCells造成ui卡顿
                dataGridView2.Columns["报警代码"].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
                dataGridView2.Columns["开始时间"].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
                dataGridView2.Columns["结束时间"].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
                dataGridView2.Columns["报警文本"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                //dataGridView2.Sort(dataGridView2.Columns["开始时间"], ListSortDirection.Descending);//倒序
                dataGridView2.RowHeadersVisible = false; //不显示不含标题的列
                dataGridView2.ReadOnly = true;//禁止用户修改值
                dataGridView2.SelectionMode = DataGridViewSelectionMode.FullRowSelect;//设定选择模式为选择整行
                dataGridView2.MultiSelect = false;//是否可以多选
                dataGridView2.AllowUserToResizeColumns = false; // 禁止用户改变DataGridView的所有列的列宽
                dataGridView2.AllowUserToResizeRows = false;//禁止用户改变DataGridView所有行的行高
                dataGridView2.AllowUserToAddRows = false;//不显示空白新增行
            }));
        }
        private void button1_Click(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                //传递this目的是让等待窗体居中
                FrmWaitting frmWaitting = new FrmWaitting(this);
                AsyncForm test = new AsyncForm(frmWaitting);
                test.Show();
                //try catch 包起来，防止出错
                try
                {
                    Stopwatch sw = new Stopwatch();
                    sw.Restart();
                    UpdataHistory();
                    sw.Stop();
                    this.Invoke(new Action(() => {
                        textBox3.Text = sw.ElapsedMilliseconds.ToString() + "ms";
                    }));
                }
                catch (Exception) { /*可选处理异常*/ }
                finally
                {
                    test.Close();
                    Function.FlushMemory();
                }
            });
        }

        private void button2_Click(object sender, EventArgs e)
        {
            data[7].Status = !data[7].Status;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            simAlarm = false;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            simAlarm = true;
        }
    }
}
